/// 参照Element UI的Cascader控件实现

import 'package:flutter/material.dart';

import '../../core/elegance_theme.dart';
import 'e_input.dart';
import 'e_tag.dart';

/// 级联选择器节点数据类型
typedef CascaderNode = Map<String, dynamic>;

/// 级联选择器配置项
class CascaderProps {
  /// 创建级联选择器配置项
  const CascaderProps({
    this.expandTrigger = 'click',
    this.multiple = false,
    this.checkStrictly = false,
    this.emitPath = true,
    this.lazy = false,
    this.lazyLoad,
    this.value = 'value',
    this.label = 'label',
    this.children = 'children',
    this.disabled = 'disabled',
    this.leaf = 'leaf',
  });

  /// 次级菜单的展开方式
  final String expandTrigger;

  /// 是否多选
  final bool multiple;

  /// 是否严格的遵守父子节点不互相关联
  final bool checkStrictly;

  /// 在选中节点改变时，是否返回由该节点所在的各级菜单的值所组成的数组，若设置 false，则只返回该节点的值
  final bool emitPath;

  /// 是否动态加载子节点，需与 lazyLoad 方法结合使用
  final bool lazy;

  /// 加载动态数据的方法，仅在 lazy 为 true 时有效
  final Function(CascaderNode, Function(List<CascaderNode>))? lazyLoad;

  /// 指定选项的值为选项对象的某个属性值
  final String value;

  /// 指定选项标签为选项对象的某个属性值
  final String label;

  /// 指定选项的子选项为选项对象的某个属性值
  final String children;

  /// 指定选项的禁用为选项对象的某个属性值
  final String disabled;

  /// 指定选项的叶子节点的标志位为选项对象的某个属性值
  final String leaf;
}

/// 级联选择器组件
class ECascader<T> extends StatefulWidget {
  /// 创建级联选择器组件
  const ECascader({
    super.key,
    this.value,
    this.options = const [],
    this.props = const CascaderProps(),
    this.size,
    this.placeholder = '请选择',
    this.disabled = false,
    this.clearable = false,
    this.showAllLevels = true,
    this.collapseTags = false,
    this.separator = ' / ',
    this.filterable = false,
    this.filterMethod,
    this.debounce = 300,
    this.beforeFilter,
    this.popperClass,
    this.onChange,
    this.onExpandChange,
    this.onBlur,
    this.onFocus,
    this.onVisibleChange,
    this.onRemoveTag,
  });

  /// 选中项绑定值
  final dynamic value;

  /// 可选项数据源
  final List<CascaderNode> options;

  /// 配置选项
  final CascaderProps props;

  /// 尺寸
  final String? size;

  /// 输入框占位文本
  final String placeholder;

  /// 是否禁用
  final bool disabled;

  /// 是否支持清空选项
  final bool clearable;

  /// 输入框中是否显示选中值的完整路径
  final bool showAllLevels;

  /// 多选模式下是否折叠Tag
  final bool collapseTags;

  /// 选项分隔符
  final String separator;

  /// 是否可搜索选项
  final bool filterable;

  /// 自定义搜索逻辑
  final bool Function(CascaderNode, String)? filterMethod;

  /// 搜索关键词输入的去抖延迟，毫秒
  final int debounce;

  /// 筛选之前的钩子
  final bool Function(String)? beforeFilter;

  /// 自定义浮层类名
  final String? popperClass;

  /// 当选中节点变化时触发
  final Function(dynamic)? onChange;

  /// 当展开节点发生变化时触发
  final Function(List<dynamic>)? onExpandChange;

  /// 当失去焦点时触发
  final Function(FocusNode)? onBlur;

  /// 当获得焦点时触发
  final Function(FocusNode)? onFocus;

  /// 下拉框出现/隐藏时触发
  final Function(bool)? onVisibleChange;

  /// 在多选模式下，移除Tag时触发
  final Function(dynamic)? onRemoveTag;

  @override
  State<ECascader<T>> createState() => _ECascaderState<T>();
}

class _ECascaderState<T> extends State<ECascader<T>> {
  late FocusNode _focusNode;
  bool _isVisible = false;
  String _searchText = '';
  List<dynamic> _expandValues = [];
  List<CascaderNode> _checkedNodes = [];
  dynamic _value;
  late List<CascaderNode> _options;

  @override
  void initState() {
    super.initState();
    _focusNode = FocusNode();
    _focusNode.addListener(() {
      if (_focusNode.hasFocus && !widget.disabled) {
        _showPanel();
      }
    });
    _options = List.from(widget.options);
    _value = widget.value;
    if (_value != null) {
      _updateCheckedNodes();
    }
  }

  @override
  void didUpdateWidget(covariant ECascader<T> oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (oldWidget.value != widget.value) {
      _value = widget.value;
      _updateCheckedNodes();
    }
    if (oldWidget.options != widget.options) {
      _options = List.from(widget.options);
      _updateCheckedNodes();
    }
  }

  void _showPanel() {
    if (!_isVisible && !widget.disabled) {
      setState(() {
        _isVisible = true;
      });
      widget.onVisibleChange?.call(true);
    }
  }

  void _hidePanel() {
    if (_isVisible) {
      setState(() {
        _isVisible = false;
      });
      widget.onVisibleChange?.call(false);
    }
  }

  void _updateCheckedNodes() {
    // 根据_value更新_checkedNodes
    _checkedNodes = [];
    if (_value == null) return;

    // 实现从value到nodes的转换逻辑
    if (widget.props.multiple) {
      // 多选模式
      if (_value is List) {
        for (var val in _value) {
          final node = ECascaderUtils.findNodeByValue(
            _options,
            val,
            widget.props,
          );
          if (node != null) {
            _checkedNodes.add(node);
          }
        }
      }
    } else {
      // 单选模式
      final node = ECascaderUtils.findNodeByValue(
        _options,
        _value,
        widget.props,
      );
      if (node != null) {
        _checkedNodes = [node];
      }
    }
  }

  void _handleNodeCheck(CascaderNode node, bool checked) {
    // 处理节点选中逻辑
    setState(() {
      if (widget.props.multiple) {
        // 多选模式
        if (checked) {
          if (!_checkedNodes.any(
            (n) => n[widget.props.value] == node[widget.props.value],
          )) {
            _checkedNodes.add(node);
          }
        } else {
          _checkedNodes.removeWhere(
            (n) => n[widget.props.value] == node[widget.props.value],
          );
        }

        // 更新value
        _value = _checkedNodes.map((n) => n[widget.props.value]).toList();
      } else {
        // 单选模式
        _checkedNodes = [node];

        // 更新value
        _value = node[widget.props.value];

        // 单选模式下选择后关闭面板
        _hidePanel();
      }
    });

    // 触发onChange回调
    widget.onChange?.call(_value);
  }

  void _handleNodeExpand(CascaderNode node) {
    // 处理节点展开逻辑
    // 需要考虑动态加载等情况
    final nodeValue = node[widget.props.value];
    setState(() {
      if (_expandValues.contains(nodeValue)) {
        _expandValues.remove(nodeValue);
      } else {
        _expandValues.add(nodeValue);
      }
    });
    widget.onExpandChange?.call(List.from(_expandValues));
  }

  void _handleClear() {
    // 处理清空逻辑
    if (!widget.disabled) {
      setState(() {
        _value = null;
        _checkedNodes = [];
      });
      widget.onChange?.call(null);
    }
  }

  void _handleRemoveTag(dynamic value) {
    // 处理移除标签逻辑
    if (!widget.disabled) {
      // 更新_value和_checkedNodes
      widget.onRemoveTag?.call(value);
    }
  }

  String _getDisplayText() {
    // 根据_checkedNodes和配置生成显示文本
    if (_checkedNodes.isEmpty) return '';

    if (widget.props.multiple) {
      // 多选模式下的显示逻辑
      return _checkedNodes.map((node) => node[widget.props.label]).join(', ');
    } else {
      // 单选模式下的显示逻辑
      final node = _checkedNodes.first;
      if (widget.showAllLevels) {
        // 显示完整路径
        final path = ECascaderUtils.getNodePath(_options, node, widget.props);
        return path.map((n) => n[widget.props.label]).join(widget.separator);
      } else {
        // 仅显示最后一级
        return node[widget.props.label];
      }
    }
  }

  List<Widget> _renderTags() {
    // 渲染标签列表
    if (!widget.props.multiple || _checkedNodes.isEmpty) return [];

    final List<Widget> tags = [];
    for (var i = 0; i < _checkedNodes.length; i++) {
      final node = _checkedNodes[i];
      final label = node[widget.props.label];
      final value = node[widget.props.value];

      tags.add(
        ETag(
          text: label,
          closable: true,
          onClose: (_) => _handleRemoveTag(value),
        ),
      );

      // 如果需要折叠标签
      if (widget.collapseTags && i == 2 && _checkedNodes.length > 3) {
        tags.add(
          ETag(text: '+${_checkedNodes.length - 3}', type: ETagType.info),
        );
        break;
      }
    }

    return tags;
  }

  @override
  Widget build(BuildContext context) {
    final theme = EleganceTheme.of(context);
    final displayText = _getDisplayText();
    final tags = _renderTags();

    return Container(
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          // 输入框部分
          GestureDetector(
            onTap: () => _showPanel(),
            child: Container(
              decoration: BoxDecoration(
                border: Border.all(
                  color: widget.disabled
                      ? theme.borderColor
                      : theme.borderColor,
                  width: theme.borderWidth,
                ),
                borderRadius: BorderRadius.circular(theme.borderRadius),
                color: widget.disabled ? theme.surfaceColor : Colors.white,
              ),
              padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
              child: Row(
                children: [
                  // 标签区域
                  if (widget.props.multiple && tags.isNotEmpty) ...[
                    Wrap(spacing: 4, runSpacing: 4, children: tags),
                  ] else ...[
                    // 显示文本
                    Expanded(
                      child: displayText.isEmpty
                          ? Text(
                              widget.placeholder,
                              style: TextStyle(
                                color: theme.textPlaceholderColor,
                                fontSize: 14,
                              ),
                            )
                          : Text(
                              displayText,
                              style: TextStyle(
                                color: theme.textPrimaryColor,
                                fontSize: 14,
                              ),
                            ),
                    ),
                  ],
                  // 右侧图标区域
                  if (widget.clearable && _value != null) ...[
                    GestureDetector(
                      onTap: _handleClear,
                      child: Icon(
                        Icons.clear,
                        size: 16,
                        color: theme.textSecondaryColor,
                      ),
                    ),
                  ],
                  Icon(
                    Icons.arrow_drop_down,
                    size: 16,
                    color: theme.textSecondaryColor,
                  ),
                ],
              ),
            ),
          ),
          // 下拉面板
          if (_isVisible) ...[
            Container(
              margin: const EdgeInsets.only(top: 4),
              decoration: BoxDecoration(
                border: Border.all(
                  color: theme.borderColor,
                  width: theme.borderWidth,
                ),
                borderRadius: BorderRadius.circular(theme.borderRadius),
                color: Colors.white,
                boxShadow: [theme.shadowMedium],
              ),
              child: Column(
                children: [
                  // 搜索框
                  if (widget.filterable) ...[
                    Container(
                      padding: const EdgeInsets.all(8),
                      child: EInput(
                        placeholder: '搜索',
                        value: _searchText,
                        onChange: (value) {
                          // 实现搜索逻辑
                          setState(() {
                            _searchText = value;
                          });
                        },
                      ),
                    ),
                  ],
                  // 级联面板
                  Container(
                    height: 300,
                    width: double.infinity,
                    child: ECascaderPanel(
                      options: _options,
                      props: widget.props,
                      value: _value,
                      expandValues: _expandValues,
                      onNodeCheck: _handleNodeCheck,
                      onNodeExpand: _handleNodeExpand,
                      onConfirm: (nodes) {
                        // 处理确认选择逻辑
                        _hidePanel();
                      },
                    ),
                  ),
                ],
              ),
            ),
          ],
        ],
      ),
    );
  }

  @override
  void dispose() {
    _focusNode.dispose();
    super.dispose();
  }
}

/// 级联选择器面板组件
class ECascaderPanel extends StatelessWidget {
  /// 创建级联选择器面板组件
  const ECascaderPanel({
    super.key,
    required this.options,
    required this.props,
    this.value,
    this.expandValues = const [],
    this.onNodeCheck,
    this.onNodeExpand,
    this.onConfirm,
  });

  /// 可选项数据源
  final List<CascaderNode> options;

  /// 配置选项
  final CascaderProps props;

  /// 选中项绑定值
  final dynamic value;

  /// 展开节点的值列表
  final List<dynamic> expandValues;

  /// 节点选中回调
  final Function(CascaderNode, bool)? onNodeCheck;

  /// 节点展开回调
  final Function(CascaderNode)? onNodeExpand;

  /// 确认选择回调
  final Function(List<CascaderNode>)? onConfirm;

  @override
  Widget build(BuildContext context) {
    final theme = EleganceTheme.of(context);

    return Container(
      decoration: BoxDecoration(
        border: Border(
          top: BorderSide(color: theme.borderColor, width: theme.borderWidth),
        ),
      ),
      child: Row(
        children: [
          // 渲染第一级菜单
          _renderMenu(options, theme),
          // 递归渲染多级菜单
          ..._renderSubMenus(options, expandValues, theme),
        ],
      ),
    );
  }

  /// 递归渲染子菜单
  List<Widget> _renderSubMenus(
      List<CascaderNode> parentNodes,
      List<dynamic> expandValues,
      EleganceThemeData theme,
      [int level = 0]) {
    final subMenus = <Widget>[];

    // 查找当前展开的节点
    for (var node in parentNodes) {
      final nodeValue = node[props.value];
      
      // 如果当前节点被展开
      if (expandValues.contains(nodeValue) && 
          node.containsKey(props.children) &&
          node[props.children] != null &&
          (node[props.children] as List).isNotEmpty) {
        
        // 渲染当前展开节点的子菜单
        final children = node[props.children] as List<CascaderNode>;
        subMenus.add(_renderMenu(children, theme));
        
        // 递归渲染更深层次的子菜单
        // 对于下一级，我们只传递相关的展开值
        final nextLevelExpandValues = expandValues.skip(1).toList();
        subMenus.addAll(_renderSubMenus(children, nextLevelExpandValues, theme, level + 1));
        
        // 每个展开节点只处理一次
        break;
      }
    }

    return subMenus;
  }

  Widget _renderMenu(List<CascaderNode> nodes, EleganceThemeData theme) {
    return Container(
      width: 180,
      child: ListView.builder(
        itemCount: nodes.length,
        itemBuilder: (context, index) {
          final node = nodes[index];
          final label = node[props.label] as String;
          final disabled = node[props.disabled] as bool? ?? false;
          final hasChildren =
              node.containsKey(props.children) &&
              node[props.children] != null &&
              (node[props.children] as List).isNotEmpty;
          // 简化实现，后续可以根据实际需求完善
          final isChecked = false;

          return GestureDetector(
            onTap: () {
              if (disabled) return;

              if (hasChildren) {
                onNodeExpand?.call(node);
              } else {
                onNodeCheck?.call(node, !isChecked);
              }
            },
            child: Container(
              padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
              decoration: BoxDecoration(color: Colors.transparent),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  Text(
                    label,
                    style: TextStyle(
                      color: disabled
                          ? theme.textPlaceholderColor
                          : isChecked
                          ? theme.primaryColor
                          : theme.textPrimaryColor,
                      fontSize: 14,
                    ),
                  ),
                  if (hasChildren) ...[
                    Icon(
                      Icons.arrow_right,
                      size: 14,
                      color: theme.textSecondaryColor,
                    ),
                  ],
                ],
              ),
            ),
          );
        },
      ),
    );
  }
}

/// 用于ECascader组件的工具方法
class ECascaderUtils {
  /// 从节点数据中查找指定值的节点
  static CascaderNode? findNodeByValue(
    List<CascaderNode> options,
    dynamic value,
    CascaderProps props, [
    bool deep = true,
  ]) {
    for (var node in options) {
      if (node[props.value] == value) {
        return node;
      }
      if (deep &&
          node.containsKey(props.children) &&
          node[props.children] != null &&
          (node[props.children] as List).isNotEmpty) {
        final found = findNodeByValue(
          node[props.children] as List<CascaderNode>,
          value,
          props,
          deep,
        );
        if (found != null) {
          return found;
        }
      }
    }
    return null;
  }

  /// 获取节点的完整路径
  static List<CascaderNode> getNodePath(
    List<CascaderNode> options,
    CascaderNode targetNode,
    CascaderProps props,
  ) {
    final path = <CascaderNode>[];
    _findPath(options, targetNode, props, path);
    return path;
  }

  static bool _findPath(
    List<CascaderNode> options,
    CascaderNode targetNode,
    CascaderProps props,
    List<CascaderNode> path,
  ) {
    for (var node in options) {
      path.add(node);
      if (node[props.value] == targetNode[props.value]) {
        return true;
      }
      if (node.containsKey(props.children) &&
          node[props.children] != null &&
          (node[props.children] as List).isNotEmpty) {
        if (_findPath(
          node[props.children] as List<CascaderNode>,
          targetNode,
          props,
          path,
        )) {
          return true;
        }
      }
      path.removeLast();
    }
    return false;
  }

  /// 根据搜索关键词过滤节点
  static List<CascaderNode> filterNodes(
    List<CascaderNode> options,
    String keyword,
    CascaderProps props,
    bool Function(CascaderNode, String)? customFilter,
  ) {
    final filtered = <CascaderNode>[];

    for (var node in options) {
      bool match = false;

      if (customFilter != null) {
        match = customFilter(node, keyword);
      } else {
        match = (node[props.label] as String).toLowerCase().contains(
          keyword.toLowerCase(),
        );
      }

      if (match) {
        filtered.add(Map.from(node));
      } else if (node.containsKey(props.children) &&
          node[props.children] != null &&
          (node[props.children] as List).isNotEmpty) {
        final children = filterNodes(
          node[props.children] as List<CascaderNode>,
          keyword,
          props,
          customFilter,
        );

        if (children.isNotEmpty) {
          final newNode = <String, dynamic>{...node};
          newNode[props.children] = children;
          filtered.add(newNode);
        }
      }
    }

    return filtered;
  }
}
